package com.ap.core.jbehave.managerefund;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import java.io.IOException;

import org.hamcrest.CoreMatchers;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;

import com.ap.core.common.types.RefundReasonType;
import com.ap.core.cxf.jaxb.common.DeliveryType;
import com.ap.core.cxf.jaxb.managepayment.ConfirmPayment1Request;
import com.ap.core.cxf.jaxb.managepayment.ConfirmPayment1Response;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Request;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Response;
import com.ap.core.cxf.jaxb.managerefund.RequestRetrieveRefundAccount;
import com.ap.core.cxf.jaxb.managerefund.ResponseRetrieveRefundAccount;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Request;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTPMessageType;
import com.ap.core.cxf.jaxb.msghdr.MessageType;
import com.ap.core.cxf.jaxb.rtp.TransactionCheckOutType;
import com.ap.core.jbehave.BaseTransitionRTPSteps;
import com.ap.core.jbehave.StoryContext;
import com.ap.core.util.JaxbUtil;
import com.ap.core.util.Nullable;
import com.ap.generator.managerefund.RequestRetrieveRefundAccountGeneratorBuilder;
import com.core.ap.wsdl.managepaymentservice_1.ManagePayment1PortType;
import com.core.ap.wsdl.managerefundservice_1.ManageRefund1PortType;
import com.core.ap.wsdl.managerefundservice_1.RetrieveRefundAccount1Fault;
import com.core.ap.wsdl.managertpservice_1.ManageRTP1PortType;

public class ManageRefundSteps extends BaseTransitionRTPSteps {
	
	private SubmitRTP1Request submitRTPRequest;
	private SubmitRTP1Response responseRTPType;
	private RetrieveRTP1Request retrieveRTPRequest;
	private RetrieveRTP1Response retrieveRTPResponse;
	private ConfirmPayment1Request confirmPayment1Request;
	private ConfirmPayment1Response confirmPayment1Response;
    private RequestRetrieveRefundAccount requestRetrieveRefundAccount;
    private ResponseRetrieveRefundAccount responseRetrieveRefundAccount;
    /**
     * @param storyContext
     */
    public ManageRefundSteps(StoryContext storyContext) {
        super(storyContext);
    }

    
    @Given("Distributor submited rtp to AP and transaction is succesful")
	public void giveDistributorSubmitsRTPAndPaymentSuccessful() throws Exception {

		final ManageRTP1PortType singnedPort = factory
				.getBean(ManageRTP1PortType.class);
		submitRTPRequest = createSubmitRTPRequest(SubmitRTPMessageType.SUBMITRTPFORMOB);
		submitRTPRequest.getRTPSummary().setTxCheckout(
				TransactionCheckOutType.NRMLCHK);
		submitRTPRequest.getRTPSenderInfo().getDistributorInfo()
				.setDistributorId("000001");
		submitRTPRequest.getRTPSenderInfo().getDetailMerchantInfo()
				.getMerchantInfo().setMerchantId("000001");
		submitRTPRequest.getDelivery().setDeliveryType(DeliveryType.DIGDEL);
		submitRTPRequest.getDelivery().setEmailAddress("abc@abc.com");

		LOG.info("Given -  the consumer Bank successfully completed a Faster Payment transaction to the Distributor/Merchant for the value of the purchase using m-com");
		JaxbUtil.newInstance().javaToXML(SubmitRTP1Request.class,
				submitRTPRequest);

		responseRTPType = singnedPort
				.submitRTP1(submitRTPRequest);

		JaxbUtil.newInstance().javaToXML(SubmitRTP1Response.class,
				responseRTPType);

		/*storyContext.put(SUBMIT_RTP_RESPONSE,
				Nullable.nullable(responseRTPType));*/
		
		doSubmitRTPResponseAssertions(Nullable.nullable(responseRTPType), submitRTPRequest);

		final ManagePayment1PortType managePaymentSignedPort = factory
				.getBean(ManagePayment1PortType.class);
		
		retrieveRTPRequest = createRetrieveRTPRequest();
		
		retrieveRTPRequest.getRequestInfo().setFIId("000001");
		retrieveRTPRequest.getRequestInfo().setFIConsumerId("ntwdcon1");
		
		 if(null == responseRTPType.getResponseInfo().getBRN()){
			 retrieveRTPRequest.getRequestInfo().setApTransactionId(responseRTPType.getResponseInfo().getApTransactionId());
			 retrieveRTPRequest.getRequestInfo().setApTRId(responseRTPType.getResponseInfo().getApTRId());
			 retrieveRTPRequest.getRequestInfo().setBRN(null); 
	        }else{
	        	retrieveRTPRequest.getRequestInfo().setApTransactionId(null);
	        	retrieveRTPRequest.getRequestInfo().setApTRId(null);
	        	retrieveRTPRequest.getRequestInfo().setBRN(responseRTPType.getResponseInfo().getBRN());            
	        }
		

		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Request.class,
				retrieveRTPRequest);
		
		retrieveRTPResponse = managePaymentSignedPort
				.retrieveRTP1(retrieveRTPRequest);

		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Response.class,
				retrieveRTPResponse);

		/*storyContext.put(RETRIEVE_RTP_RESPONSE,
				Nullable.nullable(retrieveRTPResponse));	*/
		
		final ManagePayment1PortType managePayment1PortType = factory
				.getBean(ManagePayment1PortType.class);

		/*Nullable<RetrieveRTP1Response> retrieveRTPResponse = storyContext
				.get(RETRIEVE_RTP_RESPONSE);*/
		
		doRetrieveRTPResponseAssertions(Nullable.nullable(retrieveRTPResponse.getRTPSummary()), Nullable.nullable(retrieveRTPResponse.getRTPSenderInfo()) , Nullable.nullable(retrieveRTPResponse.getMsgHdr().getMsgType().value()));

		confirmPayment1Request = createConfirmPayment1Request(MessageType.CONFIRMPAYMENT, TransactionCheckOutType.NRMLCHK , submitRTPRequest.getDelivery().getDeliveryType());

		confirmPayment1Request.getPaymtDetails().setApTransactionId(
				retrieveRTPRequest.getRequestInfo().getApTransactionId());

		confirmPayment1Request.getPaymtDetails().setApTRId(retrieveRTPResponse.getRTPIdentifier().getApTRId());

		confirmPayment1Request.getConsumerAcct().setFIId(
				retrieveRTPResponse.getConsumerInfo().getFIId());
		
		confirmPayment1Request.getPaymtDetails().getPaymentStatusInfo().setTotalPaymentReqAmount(retrieveRTPResponse.getRTPSummary().getPaymtAmtInfo().getTotalPaymentReqAmount());

		JaxbUtil.newInstance().javaToXML(ConfirmPayment1Request.class,
				confirmPayment1Request);
		LOG.info("When -  APCore receives the structurally valid CONFIRMPAYMENT request from OSB");
		
		confirmPayment1Response = managePayment1PortType
				.confirmPayment1(confirmPayment1Request);

		JaxbUtil.newInstance().javaToXML(ConfirmPayment1Response.class,
				confirmPayment1Response);

		/*storyContext.put(CONFIRM_PAYMENT_RESPONSE,
				Nullable.nullable(confirmPayment1Response));*/
		
		doConfirmPaymentResponseAssertions(Nullable.nullable(confirmPayment1Response), confirmPayment1Request, submitRTPRequest);
	}
	   
    @Given("Distributor want to submit a refund request and get the account details")
    public void givenDistributorSubmitsNonDisputedRefund() throws IOException {
    	requestRetrieveRefundAccount = RequestRetrieveRefundAccountGeneratorBuilder.getRetrieveRefundAccountTypeGenerator().build().generate();
    	requestRetrieveRefundAccount.getRefundRequestInfo().setDistributorId(submitRTPRequest.getRTPSenderInfo().getDistributorInfo().getDistributorId());
    	requestRetrieveRefundAccount.getRefundRequestInfo().setMerchantId((submitRTPRequest.getRTPSenderInfo().getDetailMerchantInfo().getMerchantInfo().getMerchantId()));
    	requestRetrieveRefundAccount.getRefundRequestInfo().setApTransactionId(responseRTPType.getResponseInfo().getApTransactionId());
    	requestRetrieveRefundAccount.getRefundRequestInfo().setApTRId((responseRTPType.getResponseInfo().getApTRId()));
        JaxbUtil.newInstance().javaToXML(RequestRetrieveRefundAccount.class, requestRetrieveRefundAccount);
    }

    
    @Given("refund request is disputed")
    public void givenDistributorSubmitsDisputedRefund() throws IOException {
    	requestRetrieveRefundAccount.getRefundRequestInfo().setRefundReasonType(RefundReasonType.DISPUTES.name());
    }

    @When("Distributor sends a refund request to AP Service")
    public void whenDistributorSendsRefundRequestToAPService() throws RetrieveRefundAccount1Fault {
        final ManageRefund1PortType manageRefund1PortType = factory.getBean(ManageRefund1PortType.class);
        responseRetrieveRefundAccount = manageRefund1PortType.retrieveRefundAccount1(requestRetrieveRefundAccount);;
        JaxbUtil.newInstance().javaToXML(ResponseRetrieveRefundAccount.class, responseRetrieveRefundAccount);
    }

    @Then("AP Service will respond with Consumer FI Details")
    public void thenAPServiceWillRespondwithConsumerFIDetails() {
        assertThat("Message Type  is not as expected", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getMsgHdr().getMsgType() == MessageType.RSPGETACCFORREFUND)));
        assertThat("Original message Id  is not as expected", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getMsgHdr().getOrgReqMsgId().equals(requestRetrieveRefundAccount.getMsgHdr().getMsgId()))));
        assertThat("DistributorInfo  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getDistributorInfo() != null)));
        assertThat("DistributorId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getDistributorInfo().getDistributorId() != null)));
        assertThat("DistributorName  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getDistributorInfo().getDistributorName() != null)));
        assertThat("MerchantInfo  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getMerchantInfo() != null)));
        assertThat("MerchantId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getMerchantInfo().getMerchantId() != null)));
        assertThat("MerchantName  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getMerchantInfo().getMerchantName() != null)));
        assertThat("RefundInfo  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo() != null)));
        assertThat("ApTransactionId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getApTransactionId() != null)));
        assertThat("ApTRId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getApTRId() != null)));
        assertThat("getCurrency  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getCurrency() != null)));
        assertThat("getRefundAmount  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getRefundAmount() != null)));
        assertThat("getRefundMethod  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getRefundMethod() != null)));
        assertThat("getRefundReasonType  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundInfo().getRefundReasonType() != null)));
        assertThat("RefundAcctDetails  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails() != null)));
        assertThat("getAcctNum  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails().getAcctNum() != null)));
        assertThat("getAcctSortCode  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails().getAcctSortCode() != null)));
        assertThat("getFIId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails().getFIId() != null)));
        assertThat("getFIConsumerId  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails().getFIConsumerId() != null)));
        assertThat("getFIShortName  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRefundAcctDetails().getFIShortName() != null)));
        assertThat("RoutingInfo   is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRoutingInfo() != null)));
        assertThat("getTargetURI  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRoutingInfo().getTargetURI() != null)));
        assertThat("getServiceVersion  is null", true, CoreMatchers.is(equalTo(responseRetrieveRefundAccount.getRoutingInfo().getServiceVersion()!= null)));
    }
}
